<?php
namespace DataWidget\widget;

use DataWidget\input\Input;
use DataWidget\input\DateTimeInput;
use DataWidget\input\SelectInput;

/**
 * 使用Input代替FormItem
 */
class FormWidget
{
    /** @var array $map 前端类型到后端类型的映射 */
    public $map=[
        "text"=>["input"=>Input::class],
        "datetime"=>["input"=>DateTimeInput::class],
        "select"=>["input"=>SelectInput::class],
    ];
    public $action="";
    public $button="提交";
    /** @var Input[] $inputs */
    public $inputs=[];
    /** @var string[] $hiddens 隐藏字段 */
    public $hiddens=[];

    static public function alloc()
    {
        return new static;
    }

    public function setMap($map)
    {
        $this->map=$map;
        return $this;
    }
    public function setAction($url,$button="")
    {
        $this->action=$url;
        if($button) $this->button=$button;
        return $this;
    }
    public function setInputs($data)
    {
        /** @var Input $instance */
        foreach($data as $item){
            $input=Input::class;
            if( isset($item["type"]) && isset($this->map[$item["type"]]) ){
                $value = $this->map[$item["type"]];
                if(is_string($value)){
                    $input=$value;
                    $item=[];
                }
                else{
                    if(isset($value["input"])){
                        $input=$value["input"];
                        unset($value["input"]);
                    }
                    $item=array_merge($item,$value);
                }
            }
            $this->inputs[]=$input::from($item);
        }
        return $this;
    }
    /**
     * @param array $data
     * @param bool $fill 如果某个字段没有传入值，是否覆盖掉默认值
     */
    public function setValues($data,$fill=true)
    {
        foreach($this->inputs as $input){
            if(isset($data[$input->code])){
                $input->setValue($data[$input->code]);
            }
            elseif($fill){
                $input->setValue(null);
            }
        }
        return $this;
    }
    public function getValues()
    {
        $data=[];
        foreach($this->inputs as $input){
            if(!in_array($input->code, $this->hide_items)){
                $data[$input->code]=$input->value;
            }
        }
        return $data;
    }

    /** 从字符串数组状态加载字段和值 */
    public function load($data,$fill=true){}
    /** 将字段和值归档为字符串数组状态 */
    public function archive(){}
    
    /** 
     * 用户输入数据
     * @deprecated
     * @return array
     */
    public function getInput($data)
    {
        foreach($this->inputs as $input){
            $input->input($data,$result);
        }
        return $result;
    }
    /** 
     * 用户输入数据
     * @return self
     */
    public function input($data)
    {
        $codes = [];
        foreach($this->inputs as $input){
            $input->input($data,$result);
            if($input->value === null) $codes[] = $input->code;
        }
        $this->hide_items = $codes;
        return $this;
    }
    /** 将当前对象转换为多维数组形式，用来绑定模板 */
    public function toArray()
    {
        $fields=[];
        foreach($this->inputs as $key => $item){
            if(!in_array($item->code, $this->hide_items)){
                $fields[$key]=$item->toArray();
            }
        }
        $data=[
            "action"=>$this->action,
            "button"=>$this->button,
            "fields"=>$fields,
            "hiddens"=>$this->hiddens,
        ];
        return $data;
    }
    /** @var string[] $hide_items 隐藏项 */
    protected $hide_items=[];
    /** @var string[] $hide_items 隐藏项 */
    protected $require_items=[];
    /** @var string[] $hide_items 隐藏项 */
    protected $non_write_items=[];
    public function setShowItems($codes)
    {
        if(!$codes) $this->hide_items = [];
        else{
            $items = [];
            $codes = explode(",", $codes);
            foreach($this->inputs as $field){
                if(!in_array($field->code,$codes)){
                    $items[] = $field->code;
                }
            }
            $this->hide_items = $items;
        }
        return $this;
    }
    public function setHideItems($codes)
    {
        if(!$codes) $this->hide_items = [];
        else{
            $this->hide_items = explode(",", $codes);
        }
        return $this;
    }
    public function setRequiredItems($codes)
    {

    }
    public function setNonWritableItems($codes)
    {

    }
}
